package cn.heygod.airsql.meta;


import cn.heygod.airsql.annotation.Column;
import cn.heygod.airsql.annotation.Table;
import cn.heygod.airsql.exception.AirSqlException;
import cn.heygod.airsql.util.StringUtil;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
 * @className: TableMetadataService
 * @author: Simon
 * @description: TODO
 * @date: 2024/1/31 4:22
 * @version: 1.0
 */
public class TableMetadataService {

    private final Map<String, TableMetadata> tableMetadataMap = new HashMap<>();

    private static TableMetadataService tableMetadataService = new TableMetadataService();

    public static TableMetadataService me(){
        return tableMetadataService;
    }

    private TableMetadataService(){

    }

    public void initializeTables(Class<?>... classes) {
        for (Class<?> clazz : classes) {
            TableMetadata tableMetadata = getTableMetadata(clazz);
            tableMetadataMap.put(clazz.getName(), tableMetadata);
        }
    }

    public String getTableName(Class<?> clazz) {
        TableMetadata meta = getTableMetadata(clazz);
        if(meta == null){
            throw new AirSqlException("Class not initialized or not found.");
        }
        return meta.getTableName();
    }

    public TableMetadata getTableMetadata(Class<?> clazz) {
        if (tableMetadataMap.containsKey(clazz.getName())) {
            return tableMetadataMap.get(clazz.getName());
        }

        Table tableAnnotation = clazz.getAnnotation(Table.class);
        if (tableAnnotation == null) {
            throw new IllegalArgumentException("Class must be annotated with @Table");
        }

        String tableName = tableAnnotation.name();
        Field[] fields = clazz.getDeclaredFields();
        ColumnMetadata[] columnMetadataArray = new ColumnMetadata[fields.length];

        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            Column columnAnnotation = field.getAnnotation(Column.class);
            //要么从Column注解得到，要么从fieldName变下划线后
            //TODO 没有从Getter方式来获得注解
            String columnName = (columnAnnotation != null && !columnAnnotation.name().isEmpty()) ?
                    columnAnnotation.name() : StringUtil.camelCaseToSnakeCase(field.getName());
            columnMetadataArray[i] = new ColumnMetadata(field.getName(), columnName);
        }

        TableMetadata tableMetadata = new TableMetadata(tableName, columnMetadataArray);
        tableMetadataMap.put(clazz.getName(), tableMetadata);
        return tableMetadata;
    }

    public String getFieldNameByColumnName(Class<?> clazz, String columnName) {
        TableMetadata tableMetadata = tableMetadataMap.get(clazz.getName());
        if (tableMetadata == null) {
            throw new IllegalArgumentException("Class not initialized or not found");
        }

       return tableMetadata.getField(columnName);
    }

    public String getColumnNameByFieldName(Class<?> clazz, String fieldName) {
        TableMetadata tableMetadata = tableMetadataMap.get(clazz.getName());
        if (tableMetadata == null) {
            throw new IllegalArgumentException("Class not initialized or not found");
        }

        return tableMetadata.getColumn(fieldName);
    }

}

